/*******************************************************************************
 * 版权：北京润尼尔网络科技有限公司，保留所有版权<br>
 * 版本：v1.0.0<br>
 * 文件：property.js<br>
 * 日期：2016年7月15日<br>
 * 作者: 王志远<br>
 * 功能：实现property change listener及property change support<br>
 * 
 * 修改记录：<br>
 * 日期 描述 更新功能<br>
 ******************************************************************************/

;(function(){
	
	//定义名称空间变量
	var namespace = {};

	//创建名称空间:Rainier.Basic
	//根据NodeJS后端还是web前端判断应该创建名称空间的根对象
	if((typeof(window) !== "undefined")){
		makeNamespace(window,"Rainier.Basic");
		namespace = window.Rainier.Basic;
	}else{
		//引用本地依赖库文件
		var ml_Interface = require("./interface");
		
		//初始化命名空间
		var Rainier = {};
		Rainier.Basic = {}; 
		namespace = Rainier.Basic;
		
		//获取依赖的类或接口
		namespace.Interface = ml_Interface.Interface;
	}
	
	//定义Rainier.Basic.Property子名称空间
	namespace.Property = {};
	
	//接口定义：Rainier.Basic.Property.PropertyChangeListener
	namespace.Property.g_InterPropertyChangeListener = 
    	new namespace.Interface("PropertyChangeListener",["onPropertyChange"]);
	
    //接口定义：Rainier.Basic.Property.PropertyChangeSupport
	namespace.Property.g_InterPropertyChangeSupport  = 
		new namespace.Interface("PropertyChangeSupport",["addPropertyChangeListener","firePropertyChange"]);
	
	/**
	 * 类型名称：Rainier.Basic.Property.PropertyChangeEvent<br>
	 * 类型功能：定义属性变化事件类<br>
	 */
	namespace.Property.PropertyChangeEvent = function(objEventSrc,sEventName,objOldValue,objNewValue){
		
		//成员变量：事件源
		this.m_objEventSrc = objEventSrc;
		
		//成员变量：事件名称
		this.m_sEventName  = sEventName;
		
		//成员变量：变化之前值
		this.m_objOldValue = objOldValue;
		
		//成员变量：变化后值
		this.m_objNewValue = objNewValue;
		
		/**
		 * 函数名称：Rainier.Basic.Property.PropertyChangeEvent.getEventSource<br>
		 * 函数功能：获取事件源<br>
		 * 函数返回：m_objEventSrc 事件源对象<br>
		 */
		this.getEventSource = function(){
			return this.m_objEventSrc;
		};
		
		/**
		 * 函数名称：Rainier.Basic.Property.PropertyChangeEvent.getEventName<br>
		 * 函数功能：获取事件源<br>
		 * 函数返回：m_sEventName 事件名称<br>
		 */
		this.getEventName = function(){
			return this.m_sEventName;
		};
		
		/**
		 * 函数名称：Rainier.Basic.Property.PropertyChangeEvent.getOldValue<br>
		 * 函数功能：获取事件旧值<br>
		 * 函数返回：m_objOldValue 获取事件旧值<br>
		 */
		this.getOldValue = function(){
			return this.m_objOldValue;
		};
		
		/**
		 * 函数名称：Rainier.Basic.Property.PropertyChangeEvent.getNewValue<br>
		 * 函数功能：获取事件新值<br>
		 * 函数返回：m_objOldValue 获取事件新值<br>
		 */
		this.getNewValue = function(){
			return this.m_objNewValue;
		};
	};
	
	
	/**
	 * 类型名称：Rainier.Basic.Property.PropertyChangeSupport<br>
	 * 类型功能：给对象添加属性变化支持功能，通过属性变化事件实现<br>
	 * 接口函数：<br>
	 * addListener:添加一个事件侦听器
	 * firePropertyChangeEvent:广播属性值变化事件
	 * 成员变量：<br>
	 */
	namespace.Property.PropertyChangeSupport = function(eventSource){
		
		//成员变量：定义事件源属性
		this.m_eventSource = eventSource;
		
		//成员变量：侦听器列表
		this.m_aListeners  = {};
		
		/**
		 * 函数名称：Rainier.Basic.Property.PropertyChangeSupport.addPropertyChangeListener<br>
		 * 函数功能：添加事件侦听器<br>
		 * 参数输入：sName			事件监听器名称<br>		   
		 * 参数输入：listenerObj 	事件监听对象<br>
		 * 函数返回：无<br>
		 * 异常信息：检查监听器是否实现了onPropertyChange<br>
		 */
		this.addPropertyChangeListener = function(sName,objListener){
			
			if(!sName || !objListener){
				return;
			}
			
			//确保侦听器已经实现onPropertyChange方法
			try{
				namespace.Interface.checkImplements(
						objListener,
						namespace.Property.g_InterPropertyChangeListener
				);
			}catch(e){
				throw e;
			}
			
			if(this.m_aListeners[sName]){
				return;
			}
			
			this.m_aListeners[sName] = objListener;
		};
		
		/**
		 * 函数名称：Rainier.Basic.Property.PropertyChangeSupport.removePropertyChangeListener<br>
		 * 函数功能：删除事件侦听器<br>
		 * 参数输入：sName 侦听器名称<br>
		 * 函数返回：无<br>
		 * 异常信息：无<br>
		 */
		this.removePropertyChangeListener = function(sName){
			delete this.m_aListeners[sName];
		};
		
		/**
		 * 函数名称：Rainier.Basic.Property.PropertyChangeSupport.firePropertyChangeEvent<br>
		 * 函数功能：广播属性变化事件<br>
		 * 参数输入：sEventName 	事件名称字符串<br>
		 * 参数输入：objOldValue	原始值<br>
		 * 参数输入：objNewValue	新值<br>
		 * 函数返回：无<br>
		 * 异常信息：无<br>
		 */
		this.firePropertyChangeEvent = function(sEventName,objOldValue,objNewValue,objOmitted){
			//创建一个属性变化事件
			var evt = new namespace.Property.PropertyChangeEvent(
							this.m_eventSource,
							sEventName,
							objOldValue,
							objNewValue
						  );
			
			//广播事件
			for ( var sKey in this.m_aListeners) {
				if(this.m_aListeners.hasOwnProperty(sKey)){
					var listener = this.m_aListeners[sKey];
					if(objOmitted){
						if(objOmitted !== listener){
							if(listener.onPropertyChange){
								this.m_aListeners[sKey].onPropertyChange(evt);
							}							
						}
					}else{
						if(listener.onPropertyChange){
							this.m_aListeners[sKey].onPropertyChange(evt);
						}	
					}
				}
			}
		};
	};
	
	if (typeof exports !== "undefined") {
		exports.Property = namespace.Property;
	} 
})();